import { Injectable } from '@nestjs/common';
import * as validator from 'validator';

/**
 * Validator 验证服务
 * 基于 NestJS 官方示例实现
 * 参考: https://docs.nestjs.cn/fundamentals/dependency-injection
 * 对应 Java: 验证工具类
 */
@Injectable()
export class ValidatorService {
  /**
   * 获取 validator 实例
   */
  getValidator() {
    return validator;
  }

  // ==================== 字符串验证 ====================

  /**
   * 判断是否为邮箱
   */
  isEmail(str: string): boolean {
    return validator.isEmail(str);
  }

  /**
   * 判断是否为URL
   */
  isURL(str: string, options?: validator.IsURLOptions): boolean {
    return validator.isURL(str, options);
  }

  /**
   * 判断是否为IP地址
   */
  isIP(str: string, version?: validator.IPVersion): boolean {
    return validator.isIP(str, version);
  }

  /**
   * 判断是否为IPv4地址
   */
  isIPv4(str: string): boolean {
    return validator.isIP(str, 4);
  }

  /**
   * 判断是否为IPv6地址
   */
  isIPv6(str: string): boolean {
    return validator.isIP(str, 6);
  }

  /**
   * 判断是否为手机号
   */
  isMobilePhone(str: string, locale?: validator.MobilePhoneLocale): boolean {
    return validator.isMobilePhone(str, locale);
  }

  /**
   * 判断是否为中文手机号
   */
  isMobilePhoneZh(str: string): boolean {
    return validator.isMobilePhone(str, 'zh-CN');
  }

  /**
   * 判断是否为身份证号
   */
  isIdentityCard(str: string, locale?: validator.IdentityCardLocale): boolean {
    return validator.isIdentityCard(str, locale);
  }

  /**
   * 判断是否为中文身份证号
   */
  isIdentityCardZh(str: string): boolean {
    return validator.isIdentityCard(str, 'zh-CN');
  }

  /**
   * 判断是否为护照号
   */
  isPassportNumber(str: string, countryCode?: string): boolean {
    // 简化实现，只检查基本格式
    return /^[A-Z0-9]{6,12}$/i.test(str);
  }

  /**
   * 判断是否为车牌号
   */
  isLicensePlate(str: string, locale?: string): boolean {
    if (!locale) {
      // 通用车牌号格式检查
      return /^[A-Z0-9]{5,8}$/i.test(str);
    }
    return Boolean(validator.isLicensePlate(str, locale));
  }

  /**
   * 判断是否为中文车牌号
   */
  isLicensePlateZh(str: string): boolean {
    // 中国车牌号格式：省份简称 + 字母 + 5位数字/字母
    return /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/.test(
      str,
    );
  }

  // ==================== 数字验证 ====================

  /**
   * 判断是否为数字
   */
  isNumeric(str: string): boolean {
    return validator.isNumeric(str);
  }

  /**
   * 判断是否为整数
   */
  isInt(str: string, options?: validator.IsIntOptions): boolean {
    return validator.isInt(str, options);
  }

  /**
   * 判断是否为浮点数
   */
  isFloat(str: string, options?: validator.IsFloatOptions): boolean {
    return validator.isFloat(str, options);
  }

  /**
   * 判断是否为十六进制
   */
  isHexadecimal(str: string): boolean {
    return validator.isHexadecimal(str);
  }

  /**
   * 判断是否为八进制
   */
  isOctal(str: string): boolean {
    return validator.isOctal(str);
  }

  /**
   * 判断是否为二进制
   */
  isBinary(str: string): boolean {
    // 检查是否为二进制字符串（只包含0和1）
    return /^[01]+$/.test(str);
  }

  /**
   * 判断是否为UUID
   */
  isUUID(str: string, version?: validator.UUIDVersion): boolean {
    return validator.isUUID(str, version);
  }

  // ==================== 字符串格式验证 ====================

  /**
   * 判断是否为字母
   */
  isAlpha(str: string, locale?: validator.AlphaLocale): boolean {
    return validator.isAlpha(str, locale);
  }

  /**
   * 判断是否为字母数字
   */
  isAlphanumeric(str: string, locale?: validator.AlphanumericLocale): boolean {
    return validator.isAlphanumeric(str, locale);
  }

  /**
   * 判断是否为ASCII
   */
  isAscii(str: string): boolean {
    return validator.isAscii(str);
  }

  /**
   * 判断是否为Base64
   */
  isBase64(str: string): boolean {
    return validator.isBase64(str);
  }

  /**
   * 判断是否为Base32
   */
  isBase32(str: string): boolean {
    return validator.isBase32(str);
  }

  /**
   * 判断是否为Base58
   */
  isBase58(str: string): boolean {
    return validator.isBase58(str);
  }

  /**
   * 判断是否为Base64URL
   */
  isBase64URL(str: string): boolean {
    // Base64URL 格式检查（不包含 +、/、= 字符）
    return /^[A-Za-z0-9_-]+$/.test(str);
  }

  /**
   * 判断是否为十六进制颜色
   */
  isHexColor(str: string): boolean {
    return validator.isHexColor(str);
  }

  /**
   * 判断是否为RGB颜色
   */
  isRgbColor(str: string, includePercentValues?: boolean): boolean {
    // RGB 颜色格式检查
    const rgbPattern =
      /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
    const rgbaPattern =
      /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0\.\d+)\s*\)$/;
    return rgbPattern.test(str) || rgbaPattern.test(str);
  }

  /**
   * 判断是否为HSL颜色
   */
  isHslColor(str: string): boolean {
    // HSL 颜色格式检查
    const hslPattern =
      /^hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*\)$/;
    const hslaPattern =
      /^hsla\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,\s*(0|1|0\.\d+)\s*\)$/;
    return hslPattern.test(str) || hslaPattern.test(str);
  }

  /**
   * 判断是否为JSON
   */
  isJSON(str: string): boolean {
    return validator.isJSON(str);
  }

  /**
   * 判断是否为JWT
   */
  isJWT(str: string): boolean {
    return validator.isJWT(str);
  }

  /**
   * 判断是否为MongoDB ObjectId
   */
  isMongoId(str: string): boolean {
    return validator.isMongoId(str);
  }

  // ==================== 长度验证 ====================

  /**
   * 判断长度是否在范围内
   */
  isLength(str: string, options?: validator.IsLengthOptions): boolean {
    return validator.isLength(str, options);
  }

  /**
   * 判断是否为空
   */
  isEmpty(str: string): boolean {
    return validator.isEmpty(str);
  }

  /**
   * 判断是否不为空
   */
  isNotEmpty(str: string): boolean {
    return !validator.isEmpty(str);
  }

  // ==================== 日期验证 ====================

  /**
   * 判断是否为日期
   */
  isDate(str: string): boolean {
    return validator.isDate(str);
  }

  /**
   * 判断是否为ISO日期
   */
  isISO8601(str: string, options?: validator.IsISO8601Options): boolean {
    return validator.isISO8601(str, options);
  }

  /**
   * 判断是否为RFC 3339日期
   */
  isRFC3339(str: string): boolean {
    return validator.isRFC3339(str);
  }

  // ==================== 网络验证 ====================

  /**
   * 判断是否为域名
   */
  isFQDN(str: string, options?: validator.IsFQDNOptions): boolean {
    return validator.isFQDN(str, options);
  }

  /**
   * 判断是否为MAC地址
   */
  isMACAddress(str: string): boolean {
    return validator.isMACAddress(str);
  }

  /**
   * 判断是否为端口号
   */
  isPort(str: string): boolean {
    return validator.isPort(str);
  }

  /**
   * 判断是否为数据URI
   */
  isDataURI(str: string): boolean {
    return validator.isDataURI(str);
  }

  /**
   * 判断是否为Magnet URI
   */
  isMagnetURI(str: string): boolean {
    return validator.isMagnetURI(str);
  }

  // ==================== 文件验证 ====================

  /**
   * 判断是否为文件扩展名
   */
  isFileExtension(str: string, extensions?: string[]): boolean {
    // 文件扩展名检查
    if (!extensions || extensions.length === 0) {
      return /\.\w+$/.test(str);
    }
    const ext = str.toLowerCase().split('.').pop();
    return ext ? extensions.map((e) => e.toLowerCase()).includes(ext) : false;
  }

  /**
   * 判断是否为MIME类型
   */
  isMimeType(str: string): boolean {
    return validator.isMimeType(str);
  }

  // ==================== 其他验证 ====================

  /**
   * 判断是否为信用卡号
   */
  isCreditCard(str: string): boolean {
    return validator.isCreditCard(str);
  }

  /**
   * 判断是否为IBAN
   */
  isIBAN(str: string): boolean {
    return validator.isIBAN(str);
  }

  /**
   * 判断是否为BIC
   */
  isBIC(str: string): boolean {
    return validator.isBIC(str);
  }

  /**
   * 判断是否为MD5
   */
  isMD5(str: string): boolean {
    return validator.isMD5(str);
  }

  /**
   * 判断是否为SHA1
   */
  isSHA1(str: string): boolean {
    // SHA1 哈希值检查（40位十六进制）
    return /^[a-f0-9]{40}$/i.test(str);
  }

  /**
   * 判断是否为SHA256
   */
  isSHA256(str: string): boolean {
    // SHA256 哈希值检查（64位十六进制）
    return /^[a-f0-9]{64}$/i.test(str);
  }

  /**
   * 判断是否为SHA384
   */
  isSHA384(str: string): boolean {
    // SHA384 哈希值检查（96位十六进制）
    return /^[a-f0-9]{96}$/i.test(str);
  }

  /**
   * 判断是否为SHA512
   */
  isSHA512(str: string): boolean {
    // SHA512 哈希值检查（128位十六进制）
    return /^[a-f0-9]{128}$/i.test(str);
  }

  /**
   * 判断是否为强密码
   */
  isStrongPassword(str: string, options?: any): boolean {
    return validator.isStrongPassword(str, options);
  }

  /**
   * 判断是否为时间
   */
  isTime(str: string, options?: validator.IsTimeOptions): boolean {
    return validator.isTime(str, options);
  }

  /**
   * 判断是否为税号
   */
  isTaxID(str: string, locale?: string): boolean {
    // 简化实现，只检查基本格式
    return /^[A-Z0-9]{8,20}$/i.test(str);
  }

  /**
   * 判断是否为中文税号
   */
  isTaxIDZh(str: string): boolean {
    return validator.isTaxID(str, 'zh-CN');
  }

  /**
   * 判断是否为VAT
   */
  isVAT(str: string, countryCode?: string): boolean {
    // 简化实现，只检查基本格式
    return /^[A-Z0-9]{8,15}$/i.test(str);
  }

  // ==================== 转换方法 ====================

  /**
   * 转换为布尔值
   */
  toBoolean(str: string, strict?: boolean): boolean {
    return validator.toBoolean(str, strict);
  }

  /**
   * 转换为日期
   */
  toDate(str: string): Date | null {
    const result = validator.toDate(str);
    return result || null;
  }

  /**
   * 转换为浮点数
   */
  toFloat(str: string): number {
    return validator.toFloat(str);
  }

  /**
   * 转换为整数
   */
  toInt(str: string, radix?: number): number {
    return validator.toInt(str, radix);
  }

  /**
   * 转换为字符串
   */
  toString(input: any): string {
    return validator.toString(input);
  }

  // ==================== 清理方法 ====================

  /**
   * 清理HTML
   */
  escape(str: string): string {
    return validator.escape(str);
  }

  /**
   * 反转义HTML
   */
  unescape(str: string): string {
    return validator.unescape(str);
  }

  /**
   * 清理字符串
   */
  stripLow(str: string, keepNewLines?: boolean): string {
    return validator.stripLow(str, keepNewLines);
  }

  /**
   * 清理白名单字符
   */
  whitelist(str: string, chars: string): string {
    return validator.whitelist(str, chars);
  }

  /**
   * 清理黑名单字符
   */
  blacklist(str: string, chars: string): string {
    return validator.blacklist(str, chars);
  }

  /**
   * 标准化邮箱
   */
  normalizeEmail(
    email: string,
    options?: validator.NormalizeEmailOptions,
  ): string | false {
    return validator.normalizeEmail(email, options);
  }

  /**
   * 标准化URL
   */
  normalizeUrl(url: string, options?: any): string | false {
    // 简化实现，只做基本的URL规范化
    try {
      const normalized = new URL(url);
      return normalized.toString();
    } catch {
      return false;
    }
  }

  // ==================== 工具方法 ====================

  /**
   * 获取字符串长度
   */
  getLength(str: string): number {
    // 获取字符串长度
    return str.length;
  }

  /**
   * 获取字符串字节长度
   */
  getByteLength(str: string): number {
    // 获取字符串字节长度（UTF-8编码）
    return Buffer.byteLength(str, 'utf8');
  }

  /**
   * 获取字符串字符长度
   */
  getCharLength(str: string): number {
    // 获取字符串字符长度（考虑Unicode字符）
    return [...str].length;
  }

  /**
   * 获取字符串单词长度
   */
  getWordLength(str: string): number {
    // 获取字符串单词长度
    return str.split(/\s+/).filter((word) => word.length > 0).length;
  }

  /**
   * 获取字符串行数
   */
  getLineLength(str: string): number {
    // 获取字符串行数
    return str.split('\n').length;
  }

  /**
   * 获取字符串段落数
   */
  getParagraphLength(str: string): number {
    // 获取字符串段落数
    return str.split(/\n\s*\n/).filter((para) => para.trim().length > 0).length;
  }

  /**
   * 获取字符串句子数
   */
  getSentenceLength(str: string): number {
    // 获取字符串句子数
    return str.split(/[.!?]+/).filter((sentence) => sentence.trim().length > 0)
      .length;
  }
}
